package com.luqili.utils.pub.json;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.*;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class JsonUtils {

    /**
     * 安静的反序列化,指定类型
     *
     * @param <T>
     * @param json
     * @param t_class
     * @param typeClass
     * @return
     */
    public static <T> T fromJsonQuiet(String json, Class<T> t_class, Class<?>... typeClass) {
        try {
            return fromJson(json, t_class, typeClass);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 反序列化,指定类型
     *
     * @param json
     * @param t_class
     * @param typeClass
     * @return
     */
    public static <T> T fromJson(String json, Class<T> t_class, Class<?>... typeClass) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        T object = null;
        try {
            ObjectMapper mapper = new ObjectMapper();
            mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
            mapper.disable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES);
            if (json != null && !"".equals(json)) {
                JavaType javeType = mapper.getTypeFactory().constructParametricType(t_class, typeClass);
                object = mapper.readValue(json, javeType);
            }
        } catch (Exception e) {
            throw new JsonException("JSON解析错误:" + json, e);
        }
        return object;
    }

    /**
     * 安静的处理，获取一个指定的属性
     *
     * @param <T>
     * @param json
     * @param nodeName
     * @param t_class
     * @return
     */
    public static <T> T fromJsonQuiet(String json, String nodeName, Class<T> t_class) {
        try {
            return fromJson(json, nodeName, t_class);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取一个指定的属性
     *
     * @param json
     * @param nodeName
     * @param t_class
     * @return
     */
    public static <T> T fromJson(String json, String nodeName, Class<T> t_class) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        T object = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode rootNode = mapper.readTree(json); // 读取Json
            JsonNode strs = rootNode.path(nodeName);
            if (!strs.isNull() && !strs.isMissingNode()) {
                object = mapper.readValue(strs.toString(), t_class);
            }
        } catch (Exception e) {
            throw new JsonException("JSON解析错误", e);
        }
        return object;
    }

    /**
     * 获取一个深层指定的属性
     *
     * @param json
     * @param nodeName
     * @param t_class
     * @return
     */
    public static <T> T fromJsonFInd(String json, String nodeName, Class<T> t_class) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        T object = null;
        ObjectMapper mapper = new ObjectMapper();
        try {
            JsonNode rootNode = mapper.readTree(json); // 读取Json
            JsonNode strs = rootNode.findPath(nodeName);
            if (!strs.isNull() && !strs.isMissingNode()) {
                object = mapper.readValue(strs.toString(), t_class);
            }
        } catch (Exception e) {
            throw new JsonException("JSON解析错误", e);
        }
        return object;
    }

    /**
     * 序列化指定对象
     *
     * @param o
     * @return
     */
    public static String toJson(Object o) {
        StringWriter sw = new StringWriter();
        ObjectMapper mapper = new ObjectMapper();
        if (null != o) {
            try {
                mapper.writeValue(sw, o);
            } catch (IOException e) {
                throw new JsonException("JSON序列化错误", e);
            }
        }
        return sw.toString();
    }

    /**
     * 序列化对象
     *
     * @param o
     * @param outNull 是否输出空值
     * @return
     */
    public static String toJson(Object o, Boolean outNull) {
        StringWriter sw = new StringWriter();
        ObjectMapper mapper = new ObjectMapper();
        if (null != o) {
            try {
                if (outNull != null && !outNull) {
                    mapper.setSerializationInclusion(Include.NON_NULL);
                }

                mapper.writeValue(sw, o);
            } catch (IOException e) {
                throw new JsonException("JSON序列化错误", e);
            }
        }
        return sw.toString();
    }

    /**
     * 字典排序
     *
     * @param o
     * @return
     */
    public static String orderToJson(Object o) {
        StringWriter sw = new StringWriter();
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
        mapper.setSerializationInclusion(Include.NON_NULL);// 去除空值
        if (null != o) {
            try {
                mapper.writeValue(sw, o);
            } catch (IOException e) {
                throw new JsonException("JSON序列化错误", e);
            }
        }
        return sw.toString();
    }

    /**
     * 将对象转换为Map
     *
     * @param src
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toHashMap(Object src) {
        return src != null ? fromJson(toJson(src), HashMap.class, String.class, Object.class) : null;
    }
}
